package org.brisling.sysman.queryService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.brisling.authorize.shiro.ShiroSecurityService;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.domain.inf.BaseTreeNodeInf;
import org.brisling.base.service.AbstractBaseQueryService;
import org.brisling.common.ConstSysParam;
import org.brisling.common.SysConfig;
import org.brisling.common.exception.DangerousOperatorException;
import org.brisling.common.util.LongUtil;
import org.brisling.common.util.StringUtil;
import org.brisling.mobile.vo.sysman.VODept;
import org.brisling.sysman.domain.Department;
import org.brisling.sysman.domain.DepartmentExtend;
import org.brisling.sysman.domain.JobRole;
import org.brisling.sysman.domain.Users;
import org.brisling.sysman.domain.VODepartment;
import org.brisling.sysman.domain.VODeptUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

@RestController
@RequestMapping("/department/query")
public class QueryDeptService extends AbstractBaseQueryService<Department>{
	
	@Autowired
	private QueryUserService qryUserService;
	
	@Autowired
	private ShiroSecurityService shiroSecurityService;
	
	@Autowired
	private QueryDictionaryService dicService;
	
	public QueryDeptService(){
		this.moduleName = ConstSysParam.MODULE_DEPARTMENT;
		this.subSystem = ConstSysParam.SUBSYSTEM_SYSMAN;
		this.tableName = ConstSysParam.VIEW_PREFIX +this.getTableName(Department.class);
		this.clazz = Department.class;
		
		typeMap = this.getTypeMap(clazz);
		
		orderMap.put("sortedid",null);			
		
	}
	
	@PersistenceContext(unitName=ConstSysParam.SUBSYSTEM_SYSMAN)
	@Autowired
	protected void setEntityManager(EntityManager entityManager){
		this.entityManager = entityManager;		
	}
	
	@RequestMapping("/mainPage.action")
	public ModelAndView getMainPage(){
		return this.getBizMainPage();
	}
	
	/**
	 * 获取模块code名称对应的页面视图
	 * @param code	模块目录中的页面名称
	 * @return
	 */
	@RequestMapping("/getPage.action")
	public ModelAndView getBizPage(@RequestParam(value="code",required=false) String code){		
		
		return this.getBizPage(null,null,code);
	}
	
	@RequestMapping("/reloadCache.action")
	public String reloadCache(){		
		SysConfig.setDeptMap(this.initMaps());
		SysConfig.setDeptExtendMap(this.initExtendMaps());
		return "200";
	}
	
	@PostConstruct
	public void initialize(){
		HashMap<Long,Department> maps= SysConfig.getDeptMap();
		if(maps==null || maps.isEmpty()){
			HashMap<Long,Department> m = this.initMaps();
			
			if( (m!=null) && !m.isEmpty()){
				SysConfig.setDeptMap(this.initMaps());
			}
		}
		
		HashMap<Long,VODepartment> voMaps= SysConfig.getDeptExtendMap();
		if(voMaps==null || voMaps.isEmpty()){
			
			HashMap<Long,VODepartment> vd = this.initExtendMaps();
			
			if( (vd!=null) && !vd.isEmpty()){
				SysConfig.setDeptExtendMap(this.initExtendMaps());
			}
		}
	}
	/* (non-Javadoc)
	 * @see org.brisling.service.sysman.DepartmentServiceInf#getEditPage()
	 */
	@RequestMapping("/editPage.action")
	public ModelAndView getEditPage(){
		return this.getBizEditPage();
	}	
	
	
	@RequestMapping("/getListDomain.action")
	public ListDomain<Department> getListDomain(@RequestBody(required=false) String body){		
		
		return super.getListDomainByConditionAndOrder(body, typeMap, orderMap,true);
	}	
	
	@RequestMapping("/getTreeListDomain.action")
	public ListDomain<Department> getTreeListDomain(@RequestParam(value="id",required=false) Long id){
		
		return this.getPagedTreeListDomain(id);
		
	}	
	
	@RequestMapping("/getTreeList.action")
	public List<Department> getTreeList(@RequestParam(value="id",required=false) Long id){
		
		
		String userid = shiroSecurityService.getCurrentUserIdentify();
		String deptid = null;
		if(id!=null){
			return this.getPagedTreeList(id);
		}else{
			//获取管理用户
			String superUserIdentify=SysConfig.getConfig(ConstSysParam.SUPER_USER_IDENTIFY);
			//判断是否管理用户或测试用户
			if(!(SysConfig.isTestUser(userid) || superUserIdentify.compareTo(userid)==0)){
				Users usr = SysConfig.getUsr(userid);
				if(usr!=null){
					List<JobRole> jobroles = usr.getJobrole();
					if(jobroles!=null && jobroles.size()>0){
						for(JobRole r:jobroles){
							if(r!=null && r.getDeptid()!=null)
							deptid = deptid ==null?r.getDeptid()+"":deptid+","+r.getDeptid();
						}
						 
					}else{
						if(usr.getDeptid()!=null){
							deptid = usr.getDeptid().toString();
						}
					}
				}
			}		
		}
		
		return this.getTreeList(deptid);			
		
	}
	
	/**
	 * 获取部门信息数据集
	 * @return
	 */
	@RequestMapping("/getList.action")
	public List<Department> getList(){		
		
		
		String sql = String.format(this.T_SQL, this.tableName);
		
		return super.getAllList(sql);	
		
	}
	
	/**
	 * 获取当前用户所管辖部门信息数据集
	 * @return
	 */
	@RequestMapping("/getCurrentUserDeptList.action")
	public List<VODept> getCurrentUserDeptList(@RequestParam(value="id",required=false)String userid,String queryModule){		
		
		
		String sql = dicService.getSqlByBizcode("qry_current_dept");
		Map<String,Object> map = new HashMap<String,Object>();
		
		String superUserIdentify=SysConfig.getConfig(ConstSysParam.SUPER_USER_IDENTIFY);
		if (!(superUserIdentify.compareTo(userid)==0)){
			if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, queryModule)){
				String deptids = this.getJobDeptids(userid);
				map.put("deptid", deptids);	
			}
		}
		
		sql = StringUtil.formatSql(sql, map);
		
		List<VODept> lists =null;
		try {
			lists= super.getClassedAllList(sql, VODept.class);
		} catch (DangerousOperatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		
		return lists;
	}
	
	/**
	 * 获取部门扩展信息数据集
	 * @return
	 */
	@RequestMapping("/getExtendList.action")
	public List<VODepartment> getExtendList(){		
		
		
		String sql = String.format(this.T_SQL, ConstSysParam.MODULE_DEPARTMENT_EXTEND);
		
		List<VODepartment> lists=null;
		try {
			lists = super.getClassedAllList(sql, VODepartment.class);
		} catch (DangerousOperatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		return lists;	
		
	}
	
	@RequestMapping("/getTreeListByOwner.action")
	public List<Department> getTreeListByOwner(@RequestParam(value="subsystem",required=false) String subsystem){
		String queryCode = null;
		if(subsystem!=null){
			queryCode = String.format("query_%1$s_all", subsystem);
		}
		
		
		String userid = shiroSecurityService.getCurrentUserIdentify();
		Long deptid = null;
		if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, queryCode)){
			Users usr = SysConfig.getUsr(userid);
			if(usr!=null && usr.getDeptid()!=null){
				deptid = usr.getDeptid();
			}
		}
		
		if(deptid!=null)
			return this.getPagedCurrentTreeList(deptid);
		else
			return this.getPagedTreeList(deptid);
		
	}
	
	/**
	 * 根据用户岗位角色所在部门进行人员过滤
	 * @param subsystem
	 * @return
	 */
	@RequestMapping("/getTreeListByJobDept.action")
	public List<Department> getTreeListByJobDept(@RequestParam(value="subsystem",required=false) String subsystem,
			@RequestParam(value="id",required=false) Long id){
		String queryCode = null;
		if(subsystem!=null){
			queryCode = String.format("query_%1$s_all", subsystem);
		}
		
		
		String userid = shiroSecurityService.getCurrentUserIdentify();
		String deptid = null;
		if(id!=null){
			return this.getPagedTreeList(id);
		}else{
			if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, queryCode)){
				Users usr = SysConfig.getUsr(userid);
				if(usr!=null){
					List<JobRole> jobroles = usr.getJobrole();
					if(jobroles!=null && jobroles.size()>0){
						for(JobRole r:jobroles){
							if(r!=null && r.getDeptid()!=null)
							deptid = deptid ==null?r.getDeptid()+"":deptid+","+r.getDeptid();
						}
						 
					}else{
						if(usr.getDeptid()!=null){
							deptid = usr.getDeptid().toString();
						}
					}
				}
			}		
		}
		
		return this.getTreeList(deptid);		
		
	}
	
	
	
	/**
	 * 合并查询部门及人员节点
	 * @param id
	 * @return
	 */
	@RequestMapping("/getConbinTree.action")
	public List<BaseTreeNodeInf> getConbinTree(@RequestParam(value="id",required=false) String id){
		
		//去除合并树的id值额外前缀
		Long _id = null;
		if(id!=null){
			id = id.substring(1);
			_id = LongUtil.getLongValue(id, null);
		}
		
		
		List<BaseTreeNodeInf> nodeList = new ArrayList<BaseTreeNodeInf>();
		
		List<Department> typeList = null;
		
		//按照用户所在科室进行部门过滤
		if(_id == null){
			typeList = this.getTreeListByOwner(null);
		}else{
			typeList = this.getTreeList(_id);
		}
		
		
		if(typeList!=null && typeList.size()>0){
			
			for(Department i:typeList){
				
				if(i.getId()!=null){
					i.setRid(LongUtil.getLongValue("1"+i.getId(),null));
				}
			}
			nodeList.addAll(typeList);
		}
		
		List<BaseTreeNodeInf> detailList=qryUserService.getConbinList(_id);
		if((detailList!=null)&&(detailList.size()>0)){
			
			for(BaseTreeNodeInf u:detailList){
				if(u.getId()!=null){
					u.setRid(LongUtil.getLongValue("2"+u.getId(),null));
				}
			}
			nodeList.addAll(detailList);
		}
		return nodeList;	
	}
	
	
	
	
	
	
	@RequestMapping("/getOne.action")
	public Department getOne(@RequestParam(value="id",required=false) Long id){
		Department d = null;
		if(id!=null){
			d = SysConfig.getDept(id);
			if(d==null || d.getId()==null){
				d = super.getOne(id);
			}
		}
		return d;
	}
	
	/**
	 * 获取部门扩展信息
	 * @param id
	 * @return
	 */
	@RequestMapping("/getExtendOne.action")
	public DepartmentExtend getExtendOne(@RequestParam(value="id",required=false) Long id){
		DepartmentExtend d = null;
		if(id!=null){
			String view = ConstSysParam.MODULE_DEPARTMENT_EXTEND;
			
			d = super.getClassedOne(view,id.toString(),DepartmentExtend.class);			
		}
		return d;
	}
	
	
	
	/**
	 * 获取诊疗部门信息
	 * @param userid	用户id
	 * @param sqlid		查询sqlid
	 * @return
	 */
	public List<VODept> getDept(String userid,String sqlid,String queryModule){
		
		if(userid!=null && sqlid!=null && queryModule!=null){
		String sql = dicService.getSqlByBizcode(sqlid);
		
		Map<String,Object> map = new HashMap<String,Object>();
		
		String superUserIdentify=SysConfig.getConfig(ConstSysParam.SUPER_USER_IDENTIFY);
		if (!(superUserIdentify.compareTo(userid)==0)){
			if(!this.isSuperDept(userid,ConstSysParam.QUERY_ALL, queryModule)){
				String deptids = this.getJobDeptids(userid);
				map.put("deptid", deptids);	
			}
		}		
		sql = StringUtil.formatSql(sql, map);
		
		List<VODept> lists =null;
		try {
			lists= super.getClassedAllList(sql, VODept.class);
		} catch (DangerousOperatorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		
		return lists;
		}
		return null;
		
	}
	
	
	/**
	 * 查询系统配置参数集合
	 * @return
	 */
	private HashMap<Long,Department> initMaps(){
		HashMap<Long,Department> maps = new HashMap<Long,Department>();
		List<Department> lists = this.getList();
		if(lists!=null &&(!lists.isEmpty())){			
			for(Department p:lists){
				maps.put(p.getId(), p);
			}
		}
		
		return maps;
	}
	
	/**
	 * 查询部门扩展信息数据集合
	 * @return
	 */
	private HashMap<Long,VODepartment> initExtendMaps(){
		HashMap<Long,VODepartment> maps = null;
		List<VODepartment> lists = this.getExtendList();
		if(lists!=null &&(!lists.isEmpty())){
			maps = new HashMap<Long,VODepartment>();
			for(VODepartment p:lists){
				maps.put(p.getId(), p);
			}
		}
		
		return maps;
	}

	
	
	private VODeptUser generateTreeList(VODeptUser parent,Map<Long,List<VODeptUser>> childMap,Map<Long,List<VODeptUser>> userMap){
		
		Long parentid = parent.getDeptid();
		//判断节点id是否存在
		if(parentid!=null && !childMap.isEmpty()){
			
			//判断子节点是否存在
			if(childMap.containsKey(parentid)){
				
				//获取子节点数据集合
				List<VODeptUser> childList = childMap.get(parentid);
				
				//删除已取出子节点数据
				childMap.remove(parentid);
				
				
				List<VODeptUser> newList = new ArrayList<VODeptUser>();
				
				
				//判断获取的子节点数据是否有效
				if(childList!=null && childList.size()>0){
					
					
					//循环迭代子节点，查找下一级子节点信息
					
					for(VODeptUser cu:childList){
						VODeptUser v =generateTreeList(cu,childMap,userMap);
						
						List<VODeptUser> ulists = null;
						if(userMap.containsKey(cu.getDeptid())){
							ulists = userMap.get(cu.getDeptid());					
						}
						
						if(v!=null){
							if(ulists!=null){
								if(v.getNodes()!=null)
									v.getNodes().addAll(ulists);
								else
									v.setNodes(ulists);;
							}
							newList.add(v);
						}else{
							
							if(ulists!=null){
								if(cu.getNodes()!=null)
									cu.getNodes().addAll(ulists);
								else
									cu.setNodes(ulists);
							}
							newList.add(cu);
						}
						
						
					}
					
				}
				
				if(userMap.containsKey(parentid)){
					List<VODeptUser> ul = userMap.get(parentid);
					if(ul!=null && ul.size()>0){
						newList.addAll(ul);
					}
				}
				
				if(newList.size()>0)
					parent.setNodes(newList);
				
			}
			
		}
		
		return parent;
		
	}
	
	private Map<Long,List<VODeptUser>> generateChildMap(List<VODeptUser> lists){
		
		Map<Long,List<VODeptUser>> maps = new HashMap<Long,List<VODeptUser>>();
		
		
		for(VODeptUser du:lists){
			
			//判断是否子节点
			if(du!=null && du.getParentid()!=null){
						
				maps = replaceMapObj(du,du.getParentid(),maps);
				
			}
		}
		
		return maps;
	
	}
	
	/**
	 * 获取用户按照部门划分的map类型数据集合
	 * @param lists
	 * @return
	 */
	private Map<Long,List<VODeptUser>> generateUserMap(List<VODeptUser> lists){
		
		Map<Long,List<VODeptUser>> maps = new HashMap<Long,List<VODeptUser>>();
		
		
		for(VODeptUser du:lists){
			
			
			//判断是否子节点
			if(du!=null && du.getDeptid()!=null){	
				
				maps = replaceMapObj(du,du.getDeptid(),maps);				
			}
		}
		
		return maps;
	
	}
	 
	private Map<Long,List<VODeptUser>> replaceMapObj(VODeptUser vu,Long mapKey,Map<Long,List<VODeptUser>> maps){
		
		List<VODeptUser> childList = null;
		if(!maps.containsKey(mapKey)){
			childList = new ArrayList<VODeptUser>();
		}else{
			childList = maps.get(mapKey);
		}
		
		//增加当前迭代对象到子集合数组
		childList.add(vu);
		
		//更新map中，当前迭代对象parentid所对应的子集合数组
		maps.put(mapKey, childList);
		
		return maps;
	}
}
